PIC−パソコン間シリアル通信 PIC送受信テスト
パソコンからPICとデータのやり取りをしてみよう!
テストの流れとしては、パソコンから文字列(文字の最後は「CR」)を送ります。 PIC側では、その文字列を受信してバッファに格納していきます。最後の文字データが格納されると、PIC側からそれまでのデータを送信出力します。ただし、受信データの格納バッファが途中で一杯になった場合には、受信を終了してデータを送信します。なお、文字列の最後には、メッセージを付加して送信を終了するものとします。
シリアル送受信動作の確認プログラム
図1にシリアル送受信のフローチャートを示します。
プログラムの解説については、「プログラムの説明」の項をご参照ください。
<受信時のフローチャート>
図1−1.シリアル送受信プログラム
フローチャート(1)
<フレーミングエラー時の処理>
図1−2.シリアル送受信プログラム
フローチャート(2)
<オーバーランエラー時の処理>
図1−3.シリアル送受信プログラム
フローチャート(3)
<送信時のフローチャート>
図1−4.シリアル送受信プログラム
フローチャート(4)
<テキストデータの送信>
図1−5.シリアル送受信プログラム
フローチャート(5)
(注)以下に示すプログラムには、ホームページ画面作成の都合上、空白として全角文字のスペースなどが挿入されています。したがって、下記プログラムリストをそのままコピーしてMPLABのソースファイルとされた場合には、エラーとなることがあります。
→ここをクリックして、下記のプログラムをダウンロードするようにしてください。
ファイル名:「rxtx.asm」 サイズ5.87kバイト
→ここをクリックして、下記のオブジェクトファイルをダウンロードするようにしてください。
ファイル名:「rxtx.hex」 サイズ463バイト
;*********************************************************** ; シリアル通信動作チェックプログラム ; パソコンから文字列(文字の最後は「CR」)を送る。 ; PIC側では、文字列を受信してバッファに格納する。 ; もしデータが、「CR」だったらそれまでのデータを送信出力する。 ; また、バッファが一杯になったときも送信する。 ; 文字列の最後には「終了」のメッセージを付加して送信を終了する。 ; ; 非同期式通信モード ; ボーレート 9600bps ; 8ビット・ノンパリティ ; 割り込みは使用しない ;*********************************************************** |
||
LIST P=PIC16F877 INCLUDE P16F877.INC |
;(1)プロセッサの種別指定 ;(2)インクルードファイルの指定 |
|
;*********************************************************** ; 変数定義とレジスタ割付 ;*********************************************************** |
||
TEMP EQU 20H POINT EQU 21H ORG 0 |
;(3)ワークエリア ; テーブルポインタ ;(4)プログラムの開始番地の指定 |
|
;*********************************************************** ; 送受信モードの初期化 ; (注)バンクの位置に注意 ;*********************************************************** |
||
BSF STATUS,RP0 MOVLW B'10111111' MOVWF TRISC MOVLW B'00100100' MOVWF TXSTA MOVLW 81H MOVWF SPBRG BCF STATUS,RP0 MOVLW B'10010000' MOVWF RCSTA |
;(5)Bank 1 へ切替 ;(6)RC7/RX(入力),RC6/TX(出力) ;(7)PORTC の設定 ;(8)8BIT,送信許可,非同期,高速 ; TXSTA レジスタの設定 ;(9)ボーレート 9600bps (20MHz:高速設定時) ; SPBRG レジスタの設定 ;(10)Bank 0 へ戻す ;(11)シリアル,8BIT,継続受信許可 ; RCSTA レジスタの設定 |
|
;*********************************************************** ; メインプログラム ; ; データを受信し、バッファに格納する。 ; もしデータが、「CR」だったらそれまでのデータを送信出力する。 ; また、バッファが一杯になったときも送信する。 ;*********************************************************** |
||
MAIN BSF STATUS,IRP MOVLW 0A0H MOVWF FSR LPRCV BTFSS PIR1,RCIF GOTO LPRCV BTFSC RCSTA,FERR GOTO FRAME BTFSC RCSTA,OERR GOTO OVER MOVF RCREG,W MOVWF INDF SUBLW 0DH BTFSC STATUS,Z GOTO SEND CHKBF INCF FSR,F BTFSS STATUS,Z GOTO LPRCV GOTO SEND FRAME MOVF RCREG,W MOVLW '?' MOVWF INDF BTFSS RCSTA,OERR GOTO CHKBF OVER BCF RCSTA,CREN BSF RCSTA,CREN MOVLW '?' MOVWF INDF GOTO CHKBF SEND MOVLW 0A0H MOVWF FSR LPSD MOVF INDF,W CALL TX MOVF INDF,W SUBLW 0DH BTFSC STATUS,Z GOTO TEXT INCF FSR,F BTFSS STATUS,Z GOTO LPSD GOTO TEXT TEXT CLRF POINT LPTEX MOVF POINT,W CALL TABLE ADDLW 0 BTFSC STATUS,Z GOTO MAIN CALL TX INCF POINT,F GOTO LPTEX TABLE ADDWF PCL,F |
; メインルーチン ; ****** データの受信ルーチン ****** ;(12)間接アドレス設定 ; バッファの先頭アドレスをセット ; 間接アドレスポインタの初期化 ;(13)USART 受信割り込みフラグビットのチェック ; PIR1 レジスタの RCIF が「0」だったら ; LPRCV ラベル間をループする ; ****** エラーチェック ****** ;(14)フレーミングエラーのチェック(1:エラー,0:正常) ; フレーミングエラー時 FRAME のラベルへ ; ジャンプする ;(15)オーバーランエラーのチェック(1:エラー,0:正常) ; オーバーランエラー時 OVER のラベルへジャンプする ; ****** 受信データの格納 ****** ;(16)RCREGレジスタから受信データを読み込む ;(17)バッファに格納 ;(18)受信データから「CR」コードを引く ;(19)演算結果がゼロかチェック(受信データは「CR」?) ; 受信データが「CR」のとき SENDのラベルへジャンプする ; ****** バッファが一杯かどうかチェック ****** ;(20)ポインタ +1 ;(21)STATUSレジスタのZフラグビットが1だったら次をスキップ ; バッファに余裕あり LPRCVのラベルへ戻り受信を続ける ; バッファが一杯 SEND のラベルへジャンプする ; ****** エラー時の処理 ****** ; <フレーミングエラー時の処理> ;(22)ダミーの入力とFERRフラグをリセット(RCREGをリードするとクリア) ;(23)「?」の文字コードをWregにロードする ; バッファに格納(「?」の文字を格納) ;(24)オーバーランエラーのチェック(1:エラー,0:正常) ; 正常であれば CHKBF のラベルへジャンプする ; ; <オーバーランエラー時の処理> ;(25)OERRのリセット(ビットCREN のクリアによりクリアする) ;(26)連続受信を許可する ;(27)「?」の文字コードをWregにロードする ; バッファに格納(「?」の文字を格納) ;(28)CHKBF のラベルへジャンプする ; ****** データの送信ルーチン ****** ;(29)バッファの先頭アドレスをセットする ; 間接アドレスポインタをリセットする ;(30)バッファに格納されているデータをWregにロードする ;(31)送信サブルーチンへ ;(32)バッファに格納されているデータをWregに再ロードする ;(33)データから「CR」コードを引く ;(34)演算結果がゼロかチェック(データは終了コード「CR」?) ; データが「CR」のとき TEXTのラベルへジャンプする ; ****** バッファにデータが残っているかチェック ****** ;(35)ポインタ +1 ;(36)STATUSレジスタのZフラグビットが1だったら次をスキップ ; バッファに残っている LPSDのラベルへ戻り送信を続ける ; バッファが空である TEXT のラベルへジャンプする ; ****** テキストデータの送信ルーチン ****** ;(37)テーブルポインタのリセット ;(38)テーブルポインタの値をWregへロードする(OFFSET) ;(39)テキストデータの読み込みサブルーチンへ ;(40)Wregレジスタに0を加算する ;(41)演算結果がゼロかチェック(テキストデータは「0」?) ;(42)テキストデータが終了を示す「0」のとき MAINへジャンプ ;(43)テキストデータを出力するため送信サブルーチンへ ;(44)テーブルポインタ +1 ;(45)LPTEX のラベルへ戻り繰り返す ; ****** テキストデータテーブル ****** ;(46)PC+OFFSET |
|
DT "終了",0,0,0,0,0,0,0,0 | ||
;(47)TABLEの定義(PC+OFFSET相当のデータを持って戻る) | ||
;*********************************************************** ; 送信サブルーチン ; 送信可能かのチェックは送信レジスタが空であることで確認 ; (つまり、TRMT=1で可能と判定する) ; (注)TXATAのあるバンクに注意 ;*********************************************************** |
||
TX MOVWF TEMP BSF STATUS,RP0 LPTX BTFSS TXSTA,TRMT GOTO LPTX BCF STATUS,RP0 MOVF TEMP,W MOVWF TXREG RETURN END |
;(48)送信するデータを変数(TEMP)に格納 ;(49)Bank 1 へ切替 ; ;(50)送信可能であるかチェック(1:可能, 0:禁止) ; 禁止であれば LPTX のラベル間を繰り返す ; ;(51)Bank 0 へ戻す ;(52)変数(TEMP)に格納していた送信データをWregにロード ;(53)送信データはTXREGレジスタを通してシリアル出力される ;(54)メインルーチンへ戻る ; ; |
【プログラムの説明】
このプログラムについて、順を追って解説を加えておきましょう。
(1)プロセッサの種別指定
定義の仕方は「PROCESSOR」か「LIST」命令を使って設定します。ここで指定するプロセッサ名称は、パッケージの種類を示すサフィックス(最後の英記号の部分)は不要です。
PROCESSOR PIC16F877
または
LIST P=PIC16F877
(2)標準ヘッダーファイルのインクルード
標準ヘッダーファイルとは、各プロセッサが持っているSFR(Special
Function Register)をラベル(記号)で使える様にするため、ラベルとハードウェアの場所とを定義しているファイルです。標準ヘッダーファイルは 「プロセッサ名.INC」というファイル名で統一されて、MPLABのディレクトリに格納されています。従って、これのインクルード方法は下記のようにして行います。
一度、参考までに標準ヘッダーファイルの内容をエディタ等で見ておくことをお勧めします。
INCLUDE P16F877.INC
または
#INCLUDE P16F877.INC
(3)変数定義とレジスタ割付
レジスタファイルアドレスを指定するときに、アドレス数値を直接指定することもできますが、数値だけでは間違いも多く、プログラム自身も分かりにくくなってしまいます。そこで、EQU命令などを使ってラベルを設定し変数を定義します。レジスタファイルアドレスは、7ビットあるので、00〜7Fまで最大128個のレジスタが指定できますが、実際に物理的に実装されて汎用的に使用できるレジスタ数はデバイスによって異なっていますので注意が必要です。
PIC16F877の汎用レジスタのアドレスは、20H〜7FH
となっていますので、20H以降のアドレスに割り付けます。
(4)プログラムの開始番地の指定
「ORG」はプログラムの開始番地を指定する擬似命令で、ORG以下の実際のプログラム命令が格納されるプログラムメモリ内の位置(アドレス)を指定します。
ORG 0 ;0番地から格納することを示します。
コンピュータは一般に電源投入時やリセットをすると必ず0番地からスタートするようになっているので、0番地には必ず命令があることが必要です。
(5)Bank 1 へ切替
PICには各種の動作モードを設定するための Special
Register と呼ばれるものが用意されています。PICを動作させるためには、まずこのSpecial
Registerの設定から始めます。そしてそれらは全て、Register
File と呼ぶメモリとして用意されています。その
Register Fileは Bank0, Bank1, Bank2, Bank3
とよばれるアドレス空間をもっているため、多少アクセスの仕方が面倒です。つまりRESET後の通常はBank0となっているので、Bank1側のレジスタにアクセスするときはBankの切替えをしてからとなります。またBank0とBank1に同じ物があるときにはどちらでも同じ様に使えます。
Bank1へ切り替える方法ですが、「STATUS」レジスタにある2ビットのRP0、RP1を変えてBankを指定します。デフォルトは、Bank0です。表1にBankとRP1,RP0ビットとの関係を示します。Bank1へ切り替えるためには、RP0ビットを「1」にします。(RP1はデフォルトで「0」なので変える必要はない。)
BSF STATUS,RP0
「STATUS」レジスタのRP0ビットを「1」にする。
Bank | RP1 | RP0 |
0 | 0 | 0 |
1 | 0 | 1 |
2 | 1 | 0 |
3 | 1 | 1 |
(6)RC7/RX(入力),RC6/TX(出力)
シリアル通信の入出力ポートとして、受信入力ポート(RC7/RX)と、送信出力ポート(RC6/TX)を使います。他のRCポートは使いませんので、とりあえず入力に設定しておきます。したがって、RC6のみ出力設定にします。
ということで、B’10111111’ (BFH)をWregにロードする。
(7)PORTC の設定
Wregの内容をTRISCレジスタに上書きする。
(8)8BIT,送信許可,非同期,高速,TXSTA レジスタの設定
「シリアル通信機能」の制御用レジスタの解説項目でTXSTAレジスタを参照してください。
TXSTAレジスタの内容
ということで、TXSTA→B’00100100’ (24H)
(9)ボーレート 9600bps (20MHz:高速設定時), SPBRG レジスタの設定
「シリアル通信機能」のSPBREGレジスタの解説項目で表3.SPBRGの設定値とボーレートを参照してください。ボーレートを9600bpsに設定します。表3−1の低速モードや、表3−2の高速モードがありますが、ここでは高速モードの9600bpsを選択します。クロック周波数が20MHzの場合は、低速モードより高速モードの方がエラーレートが小さいためです。したがって、高速モードの場合のSPBREGは、81Hに設定すればよいことが分かります。
(注)MicroChip社のデータシートは、SPBREGの設定表示は10進数(decimal)になっていますので注意してください。
(10)Bank 0 へ戻す
Bank1での設定が終了した後は、Bank0に戻しておきます。Bank1へ切り替えるためには、RP0ビットを「0」にします。(RP1はデフォルトで「0」なので変える必要はない。)
BCF STATUS,RP0
「STATUS」レジスタのRP0ビットを「0」にする。すなわち、Bank0に戻す。」
(11)シリアル,8BIT,継続受信許可,RCSTA レジスタの設定
「シリアル通信機能」の制御用レジスタの解説項目でRCSTAレジスタを参照してください。
RCSTAレジスタの内容の決定
ということで、RCSTA→B’10010000’ (90H)
(12)間接アドレス設定
バッファの先頭アドレスをセット 間接アドレスポインタの初期化
データメモリのアクセス方法に、直接レジスタのアドレスを指定してアクセスする直接アドレッシングのほかに、間接アドレッシングという方法があります。間接アドレッシングは、FSRレジスタ(File
Selection Register)と、STATUSレジスタ中のIRPビットを使います。このFSRレジスタがプログラム中で自由に書き換えられるので、プログラム中にバッファなどを作って連続した領域を順にアクセスするのに便利に使えます。また、間接アドレッシングで指定されたデータメモリは、INDFレジスタを経由して間接的にアクセスします。すなわち、指定したデータメモリに書き込む場合には、INDFレジスタに書き込み、指定したデータメモリの内容を読み出すときには、INDFレジスタの内容を読み込みます。
図2に間接アドレッシングでのデータメモリ・アドレス指定についての解説図を示します。
![]() |
図2.間接アドレッシングのデータメモリ・アドレス指定について |
(プログラム例)Bank3の汎用データメモリのアドレス20Hを指定したいとき
STATUSレジスタのRP0,RP1を使ってBankの切り替えをする必要はありません、次のように直接任意のBankをアクセスします。図2のBank指定から、STATUSレジスタのIRPを「1」、FSRレジスタの7ビット目を「1」にします。
また、場所アドレスの指定からFSRレジスタの6〜0ビット目を、20Hにしますが、7ビット目が「1」になっていますので、FSRレジスタは、A0Hにします。したがって、
BSF STATUS,IRP ;STATUSレジスタのIRPビットを「1」にする。
MOVLW 0A0H ;A0HをWregレジスタにロードする
MOVWF FSR ;Wregレジスタの内容をFSRレジスタに格納する。
となります。
(13)USART 受信割り込みフラグビットのチェック(1:USART 受信バッファがフル,
0:空)
受信バッファが空であれば LPRCV のラベル間を繰り返す
周辺機能の割り込みのフラグビットが割り当てられているPIR1レジスタのUSART
受信割り込みフラグビット(RCIF)の状態をチェックします。
USART受信バッファがフルであるとすると、RCIFが「1」となり、次の命令で分岐されます。
BTFSS PIR1,RCIF
「PIR1」レジスタのRCIFビットが「1」だったら次の命令をスキップし、ループから抜けます。
GOTO LPRCV
ただし、受信バッファが空の間は、「PIR1」レジスタのRCIFビットが「0」のままですので、LPRCVラベルへ戻ってループを繰り返します。
(14)フレーミングエラーのチェック(1:エラー,0:正常)
受信ステータスおよびコントロールレジスタであるRCSTAレジスタのフレーミングエラービット(FERR)の状態をチェックします。
BTFSC RCSTA,FERR
「RCSTA」レジスタのFERRビットが正常の「0」だったら次の命令をスキップし、オーバーランエラーのチェックへ進みます。
GOTO FRAME
フレーミングエラー時 FRAME のラベルへジャンプします。
(15)オーバーランエラーのチェック(1:エラー,0:正常)
受信ステータスおよびコントロールレジスタであるRCSTAレジスタのオーバーランエラービット(OERR)の状態をチェックします。
BTFSC RCSTA,OERR
「RCSTA」レジスタのOERRビットが正常の「0」だったら次の命令をスキップし、受信データの格納へ進みます。
GOTO OVER
オーバーランエラー時 OVERのラベルへジャンプします。
(16)RCREGレジスタから受信データを読み込む
RCREGレジスタ(受信データが格納されている)内容をWregへロードする。
(17)バッファに格納
データメモリに書き込む場合には、INDFレジスタを経由して間接的に書き込みます。
MOVWF INDF
INDFレジスタにWregの内容を格納(→間接アドレッシングで指定したデータメモリに格納される)
(18)受信データから「CR」コードを引く
「CR」コードについては、制御コード表を参照ください。16進で0DHになります。
もし、「CR」コードであれば、このときZフラグビットが「1」になります。
(19)演算結果がゼロかチェック(受信データは「CR」?)
受信データが「CR」のとき SENDのラベルへジャンプする
BTFSC STATUS,Z
Zフラグビットが「0」のとき(「CR」コードでなかったとき)、次の命令をスキップし受信動作を続けます。
GOTO SEND
「CR」コードであれば、このときZフラグビットが「1」になりますので、SENDのラベルへジャンプし送信動作に入ります。
(20)ポインタ +1
バッファの間接アドレスポインタを+1にして、次のアドレスを指定します。
もし、バッファが一杯のとき(アドレス位置が7F)であれば、+1にしたときにFSRレジスタが「0」になりますので、Zフラグビットが「1」になります。
(21)バッファが一杯か、余裕があるかの判断
BTFSS STATUS,Z
Zフラグビットが「1」のとき(バッファが一杯のとき)、次の命令をスキップし受信動作を続けます。
GOTO LPRCV
バッファに余裕あり LPRCVのラベルへ戻り受信を続ける
GOTO SEND
バッファが一杯のときSEND のラベルへジャンプし送信動作に入ります。
(22)ダミーの入力(RCREGをリードするとFERRがクリアされる)
<フレーミングエラー時の処理>
受信時にフレーミングエラーが発生した場合、フレーミングエラービットFREEが「1」となっています。
フレーミングエラービットをリセットする場合には、RCREGレジスタ(USART受信レジスタ)をWregにロードするというダミー命令を実行します。
(23)「?」の文字コードをWregにロード
バッファに格納(「?」の文字を格納)
フレーミングエラー時の処理として、「?」の文字コードをバッファに格納しておくことにします。
データメモリに書き込む場合には、INDFレジスタを経由して間接的に書き込みます。
(24)オーバーランエラーのチェック(1:エラー,0:正常)
正常であれば CHKBF のラベルへジャンプする
受信ステータスおよびコントロールレジスタであるRCSTAレジスタのオーバーランエラービット(OERR)の状態をチェックします。
BTFSS RCSTA,OERR
「RCSTA」レジスタのOERRビットがエラーの「1」だったら次の命令をスキップし、オーバーランエラーのチェックへ進みます。
GOTO CHKBF
正常時 CHKBFのラベルへジャンプし、バッファが一杯かどうかのチェックへ進みます。
(25)OERRのリセット(ビットCREN のクリアによりクリアする)
<オーバーランエラー時の処理>
受信時にオーバーランエラーが発生した場合、オーバーランエラービットOERRが「1」となっています。
オーバーランエラービットをリセットする場合には、RCSTAレジスタ(受信ステータスおよびコントロールレジスタ)の連続受信イネーブルビット(CREN)をクリアすることにより、オーバーランエラービット(OERR)がクリアされます。
(26)連続受信を許可する
先のオーバーランエラー時の処理で連続受信イネーブルビット(CREN)がクリアされてしまっているので、元の「1」にセットして戻しておきます。
(27)「?」の文字コードをWregにロード
バッファに格納(「?」の文字を格納)
オーバーランエラー時の処理として、「?」の文字コードをバッファに格納しておくことにします。
データメモリに書き込む場合には、INDFレジスタを経由して間接的に書き込みます。
(28)CHKBF のラベルへジャンプする
オーバーランエラーが発生したことを確認するための例です。
CHKBFのラベルへジャンプし、バッファが一杯かどうかのチェックへ進みます。
(29)バッファの先頭アドレスをセット 間接アドレスポインタをリセットする
データの送信ルーチンに入ったとき、格納されているバッファの先頭に間接アドレスポインタをセットします。
STATUSレジスタのIRPは「1」のまま変化していませんので、あえてセットする必要はありません。FSRの設定を(12)の項目と同じA0Hにセットします。
(30)バッファに格納されているデータをWregにロードする
バッファに書き込まれたデータを読み込む場合には、INDFレジスタを経由して間接的に読み込みます。
(31)送信サブルーチンへ
送信のサブルーチンへジャンプします。
(32)バッファに格納されているデータをWregに再ロードする
文字コードが「CR」であるかどうか判断するためにWregレジスタに再ロードします。
バッファに書き込まれたデータを読み込む場合には、INDFレジスタを経由して間接的に読み込みます。
(33)データから「CR」コードを引く
「CR」コードについては、制御コード表を参照ください。16進で0DHになります。
もし、「CR」コードであれば、このときZフラグビットが「1」になります。
(34)演算結果がゼロかチェック(データは終了コード「CR」?)
データが「CR」のとき TEXTのラベルへジャンプする
BTFSC STATUS,Z
Zフラグビットが「0」のとき(「CR」コードでなかったとき)、次の命令をスキップし受信動作を続けます。
GOTO TEXT
「CR」コードであれば、このときZフラグビットが「1」になりますので、TEXTのラベルへジャンプし「終了」の文字コードを送信する動作に入ります。
(35)ポインタ +1
バッファの間接アドレスポインタを+1にして、次のアドレスを指定します。
もし、バッファが一杯のとき(アドレス位置が7F)であれば、+1にしたときにFSRレジスタが「0」になりますので、Zフラグビットが「1」になります。
(36)バッファにデータが残っているかチェック
BTFSS STATUS,Z
Zフラグビットが「1」のとき(バッファが一杯のとき)、次の命令をスキップし、「終了」の文字コードを送信する動作に入ります。
GOTO LPSD
バッファデータが残っている LPSDのラベルへ戻り送信を続ける
GOTO TEXT
バッファデータが空である。TEXT のラベルへジャンプし、「終了」の文字コードを送信する動作に入ります。
(37)テーブルポインタのリセット
送信文字列(テープル)の位置を示すテーブルポインタを「0」にします。
(先頭の文字位置に設定)
(38)テーブルポインタの値をWregへロードする(OFFSET)
送信文字列(テープル)の位置を示すテーブルポインタをWregにロードします。
このときの数値が、プログラムカウンタのオフセットになります。
(39)テキストデータの読み込みサブルーチンへ
送信文字列が書かれたテキストデータの読み込みサブルーチンへジャンプします。
(40)Wregレジスタに0を加算する
Wregレジスタには、PC+OFFSET相当の文字データ(送信すべき文字)が入っています。ここで文字データに数値「0」を加算します。加算値が「0」ですので、当然加算前後で文字データそのものには変化はありません。ところで、(40)番のTABLEで定義された文字列の最後の方に0を並べておきました。
(41)演算結果がゼロかチェック(テキストデータは「0」?)
ゼロステータスが「0」のまま(文字データ有)であったならば、次の命令をスキップします。ゼロステータスが「1」(文字データ無)であったならば、次の命令を実行します。
(42)テキストデータが終了を示す「0」のとき END_LPへジャンプ
先の判断分岐命令で、ゼロステータスが「1」(文字データ無)であったならば、この命令が実行されます。すなわち、送信終了のループ(END_LP)にジャンプします。
(43)テキストデータを出力するため送信サブルーチンへ
先の判断分岐命令で、ゼロステータスが「0」のまま(文字データ有)であったならば、この命令を実行します。すなわち、文字データを出力するための送信ルーチンへジャンプします。
(44)テーブルポインタ +1
テーブルポインタの値(オフセット)を+1します。
(45)LPTEX のラベルへ戻り繰り返す
LPTEXのラベルまで戻り繰り返す。
(46)PC+OFFSET
テキストデータテーブルのサブルーチンに来ると、プログラムカウンタに、Wregの値(オフセット)が加算されます。その加算結果をプログラムカウンタとしますので、そのアドレスで指定された文字データを示すようになります。
ADDWF PCL,F ;プログラムカウンタに、Wregの値(オフセット)を加算し、
その加算結果をプログラムカウンタする。
(47)TABLEの定義(PC+OFFSET相当のデータを持って戻る)
DTは、テーブルデータをプログラムメモリ内に定義する疑似命令です。また、データをWregにセットしてサブルーチンから復帰します。すなわち、PC+OFFSET相当の文字データを持って戻ります。
(48)送信するデータを変数(TEMP)に格納
Wregにある送信文字データを変数TEMPに格納して退避させておきます。
(49)Bank 1 へ切替
送信レジスタステータスビット(TRMT)の状態を確認するため、 TXSTAレジスタのあるBank1へ切り替えます。
(50)送信可能であるかチェック(1:可能, 0:禁止)
禁止であれば LPTX のラベル間を繰り返す
TXSTAレジスタの送信レジスタステータスビット(TRMT)の状態をチェックします。
送信が可能であるとすると、TRMTが「1」となり、次の命令で分岐されます。
BTFSS TXSTA,TRMT
「TXSTA」レジスタのTRMTビットが「1」だったら次の命令をスキップし、ループから抜けます。
GOTO LPTX
ただし、送信が禁止の間は、「TXSTA」レジスタのTRMTビットが「0」のままですので、LPTXラベルへ戻ってループを繰り返します。
(51)Bank 0 へ戻す
「TXSTA」レジスタの送信レジスタステータスの内容を確認したら、Bank0に戻しておきましょう。
(52)変数(TEMP)に格納していた送信データをWregにロード
変数TEMPに格納して退避させておいた文字をパソコン側へ送信します。
(53)TXREGレジスタを通してシリアル出力
Wregに格納してあったデータを、TXREGレジスタにロードすることで、データがシリアル出力されます。
(54)メインルーチンへ戻る
RETURN命令でメインルーチンへ復帰します。
シリアル送受信動作の確認
図3にパソコンからデータを送るときのAcknowrich表示画面を示します。送信データ入力エリアから文字データを送信できます。データはTEXT/BINARYモードがありますが、TEXTモードで例として、アルファベットa〜zまでの文字列を送信することにしました。キーボードで文字列を入力した後、シフト+リターンで改行コードを最後につけて送信されます。
![]() |
図3.データを送るときのAcknowrich表示画面(テキストモード) |
図4に、文字列を送信した後のAcknowrich表示画面を示します。通信ログエリアに送受信データが表示されます。
送受信の結果は、色分けして表示されます。デフォルトの設定では、青色文字が送信データで、赤色文字が受信データを示します。送信文字の最後に↓がありますが、これが改行コードを最後につけて送信されたことを意味します。また、受信文字の最後には、「終了」の文字が付加されていることがわかります。
![]() |
図4.データ送信後のAcknowrich表示画面(テキストモード) |
次に、PICの入力バッファの確認のため、数字を1から入力していきました。PICのプログラムで、バッファ領域はBank3の20H〜7FH(32〜126)と割付ていますから、95文字分が格納できるはずです。図5に示すように、文字数が95文字となったときに、赤色の受信データが表示されました。(青色数字が送信データになります。)
![]() |
図5.入力バッファの確認テスト結果(95文字まで格納できていることがわかる) |
![]() |
|
![]() |